/**
 * 投诉
 */
import * as mars3d from "mars3d"
import * as turf from "@turf/turf"
import { listComplainArea } from "@mars/api/data/index"
import { ref } from "vue"
import { useWidget } from "@mars/common/store/widget"
const Cesium = mars3d.Cesium
const { activate, getWidget } = useWidget()
export const eventTarget: mars3d.BaseClass = new mars3d.BaseClass()

let map: mars3d.Map // 地图对象
let graphicLayer: mars3d.layer.GraphicLayer
let _last_basemap: string | number | mars3d.layer.BaseTileLayer
let heatLayer: mars3d.layer.HeatLayer
const boundarypath : string = import.meta.env.VITE_APP_BOUNDARY_PATH as string


// 初始化当前业务
export function onMounted(mapInstance: mars3d.Map) {
  map = mapInstance // 记录map
  // 创建矢量数据图层
  graphicLayer = new mars3d.layer.GraphicLayer()
  map.addLayer(graphicLayer)
  initCameraView()

}
export function initCameraView() {
  map.setCameraView({ lat: 31.531747, lng: 120.730147, alt: 17769.2, heading: 359.9, pitch: -55.5 })
}
// 释放当前业务
export function onUnmounted(): void {
  if (_last_basemap) {
    map.basemap = _last_basemap // 还原底图
    _last_basemap = null
  }
  if (heatLayer) {
    map.removeLayer(heatLayer, true)
    heatLayer = null
  }

  map.cancelFlyTo()
  graphicLayer.remove()
  graphicLayer = null

  map.off(mars3d.EventType.mouseMove)
  map.off(mars3d.EventType.click)
  map = null
}

const positions = ref<any[]>([])
const dataMap = new Map<string, any>()

export async function initMap() {
  // disable(["sb-query"])

  const data = await getComplainAreaList()

  const currentData = data.map(item => {
    const complainVos = item.iatComplainAdministrationVos
    let sumLng = 0
    let sumLat = 0
    let count = 0
    complainVos.forEach((elemt) => {
      // console.log("iatComplainAdministrationVos======", elemt.lng, elemt.lat)
        // 确保lng和lat存在且是有效数字
        if (elemt.lng && !isNaN(parseFloat(elemt.lng)) && 
            elemt.lat && !isNaN(parseFloat(elemt.lat))) {
            sumLng += parseFloat(elemt.lng)
            sumLat += parseFloat(elemt.lat)
            count++
        }
      })
    
    if (count === 0) {
      return null
    }  
    const lng = sumLng / count
    const lat = sumLat / count
    const keys = lng + "_" + lat
    dataMap.set(keys, complainVos)
    return {
      lng,
      lat,
      value: item.total,
      keys
    }
  })


  positions.value = await getPositions()


  // 根据positions,currentViewData 生成热力图
  // 转换数据边界点为热力图点（低权重）
  // const pointsFromB = positions.value.map(coord => ({
  //   lng: coord[0],
  //   lat: coord[1],
  //   value: 0 // 边缘点权重较低
  // }))

  // 合并数据
  const heatmapData = currentData && currentData.length > 0
  ? [
      ...currentData.map(item => ({ 
        lng: item.lng, 
        lat: item.lat, 
        value: Number(item.value)
      }))
      // ...pointsFromB
    ]
  : [] // 或者返回空数组 []

  console.log("heatmapData==========", heatmapData)
  creatHeatLayer(heatmapData)
}


// 获取投诉
export async function getComplainAreaList() {
  const res:any = await listComplainArea({
    distance: 200
  })
  return res.data
}

// 获取三环区域的所有坐标点位
export async function getPositions() {
  try {
    const geojson = await mars3d.Util.fetchJson({
      url: boundarypath
    })
    
    const arr = mars3d.Util.geoJsonToGraphics(geojson)
    return arr.flatMap(item => item.positions || [])
  } catch (error) {
    console.error("获取坐标点位失败:", error)
    return []
  }
}


// 生成热力图
export function creatHeatLayer(arrPoints) {

  // 测试点数据，实际开发时换掉
  // 热力图 图层
  heatLayer = new mars3d.layer.HeatLayer({

    positions: arrPoints,
    // 以下为热力图本身的样式参数，可参阅api：https://www.patrick-wied.at/static/heatmapjs/docs.html
    heatStyle: {
      radius: 40,
      blur: 0.85
    },
    min: 0,
    // 以下为矩形矢量对象的样式参数
    style: {
      height: 0,
      opacity: 0.4
    },
    // flyTo: true,
    //  name: this.config.name,
    pid: 99 // 图层管理 中使用，父节点id
  })
  map.addLayer(heatLayer)
  // 鼠标移入/移出事件
  // let lastHighlight = null

  map.on(mars3d.EventType.mouseMove, (e) => {
    const point = mars3d.LngLatPoint.fromCartesian(e.cartesian)
    const data = heatLayer.getPointData(point)
    if (!data.x || data.value === 0) {

      const nearestPoint = findNearestPoint(arrPoints, point)
      if (nearestPoint) {
        const neareData = heatLayer.getPointData(nearestPoint)
        const inhtml = `
        经度: ${point.lng} <br />
        纬度: ${point.lat} <br />
        投诉次数: ${neareData.value} <br />
        颜色: <span style="background-color: ${neareData.color};padding:2px 5px;">${neareData.color}</span>
        `
        map.openSmallTooltip(e.windowPosition, inhtml)
        return
      } else {
        map.closeSmallTooltip()
        return
      }

     
    }
    const inhtml = `
      经度: ${point.lng} <br />
      纬度: ${point.lat} <br />
      投诉次数: ${data.value} <br />
      颜色: <span style="background-color: ${data.color};padding:2px 5px;">${data.color}</span>
      `
    map.openSmallTooltip(e.windowPosition, inhtml)
  })

  map.on(mars3d.EventType.click, (e) => {
    const point = mars3d.LngLatPoint.fromCartesian(e.cartesian)
    const data = heatLayer.getPointData(point)
    if (!data.x || data.value === 0) {
      const nearestPoint = findNearestPoint(arrPoints, point)
      if (nearestPoint) {
        const keys = nearestPoint.lng + "_" + nearestPoint.lat
        const complaintData = findClosestObject(dataMap, keys)
        eventTarget.fire("loadComplaintData", { data: complaintData })
      }
      return
    }
    
    const keys = point.lng + "_" + point.lat
    const complaintData = findClosestObject(dataMap, keys)
    eventTarget.fire("loadComplaintData", { data: complaintData })
  })


}


function findClosestObject(map, targetKey) {
  // Parse target coordinates
  const [targetLng, targetLat] = targetKey.split("_").map(Number)
  
  let closestKey = null
  let minDistance = Infinity

  // Iterate through all keys in the map
  for (const key of map.keys()) {
    const [lng, lat] = key.split("_").map(Number)
    
    // Calculate distance using Haversine formula
    const distance = haversineDistance(
      { latitude: targetLat, longitude: targetLng },
      { latitude: lat, longitude: lng }
    )
    
    if (distance < minDistance) {
      minDistance = distance
      closestKey = key
    }
  }
  
  return closestKey ? map.get(closestKey) : null
}

// Haversine distance calculation
function haversineDistance(coord1, coord2) {
  const R = 6371 // Earth radius in km
  const dLat = deg2rad(coord2.latitude - coord1.latitude)
  const dLon = deg2rad(coord2.longitude - coord1.longitude)
  const a = 
    Math.sin(dLat / 2) * Math.sin(dLat / 2) +
    Math.cos(deg2rad(coord1.latitude)) * Math.cos(deg2rad(coord2.latitude)) * 
    Math.sin(dLon / 2) * Math.sin(dLon / 2)
  const c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1 - a)) 
  return R * c
}

function deg2rad(deg) {
  return deg * (Math.PI / 180)
}


// 辅助函数：查找最近点（基于简单欧氏距离）
function findNearestPoint(points, target, threshold = 0.003) {
  let minDist = Infinity
  let result = null
  points.forEach(p => {
    const dist = Math.sqrt(
      Math.pow(p.lng - target.lng, 2) + Math.pow(p.lat - target.lat, 2)
    )
    if (dist < threshold && dist < minDist) {
      minDist = dist
      result = p
    }
  })
  return result
}
